// import com.alibaba.druid.sql.ast.SQLExpr;
// import com.alibaba.druid.sql.ast.SQLHint;
// import com.alibaba.druid.sql.ast.statement.SQLErrorLoggingClause;
// import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
// import com.alibaba.druid.sql.ast.statement.SQLSelect;
// import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObject;
// import com.alibaba.druid.sql.dialect.oracle.ast.OracleSQLObjectImpl;
// import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
// import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.util.ArrayList;
// import java.util.List;

#include "OracleMultiInsertStatement.h"
#include "../../../../ast/statement/SQLErrorLoggingClause.h"
#include "../../../../ast/statement/SQLSelect.h"
#include "../../../../ast/statement/SQLExprTableSource.h"
#include "../../../../ast/statement/SQLInsertStatement.h"
#include "../../../../ast/SQLExpr.h"
#include "../../../../ast/SQLHint.h"
#include "../clause/OracleReturningClause.h"
#include "../../visitor/OracleASTVisitor.h"
#include "../../../../visitor/SQLASTVisitor.h"
#include "../../../../../utils/listTran.h"

OracleMultiInsertStatement_Option_ptr OracleMultiInsertStatement_Option::ALL = OracleMultiInsertStatement_Option_ptr(new OracleMultiInsertStatement_Option(1ULL << 0, make_string_ptr("ALL")));
OracleMultiInsertStatement_Option_ptr OracleMultiInsertStatement_Option::FIRST = OracleMultiInsertStatement_Option_ptr(new OracleMultiInsertStatement_Option(1ULL << 1, make_string_ptr("FIRST")));

OracleMultiInsertStatement_Option::OracleMultiInsertStatement_Option(uint64_t mask, string_ptr name)
{
  this->mask = mask;
  this->name = name;
}

OracleMultiInsertStatement_ConditionalInsertClause::OracleMultiInsertStatement_ConditionalInsertClause()
{
  items = std::make_shared<std::list<OracleMultiInsertStatement_ConditionalInsertClauseItem_ptr>>();
}
OracleMultiInsertStatement_InsertIntoClause_ptr OracleMultiInsertStatement_ConditionalInsertClause::getElseItem()
{
  return elseItem;
}

void OracleMultiInsertStatement_ConditionalInsertClause::setElseItem(OracleMultiInsertStatement_InsertIntoClause_ptr elseItem)
{
  this->elseItem = elseItem;
}

OracleMultiInsertStatement_ConditionalInsertClauseItem_list_ptr OracleMultiInsertStatement_ConditionalInsertClause::getItems()
{
  return items;
}

void OracleMultiInsertStatement_ConditionalInsertClause::addItem(OracleMultiInsertStatement_ConditionalInsertClauseItem_ptr item)
{
  if (item != nullptr)
  {
    item->setParent(SharedObject(OracleMultiInsertStatement_ConditionalInsertClause));
  }
  this->items->push_back(item);
}

// @Override
void OracleMultiInsertStatement_ConditionalInsertClause::accept0(OracleASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(OracleMultiInsertStatement_ConditionalInsertClause)))
  {
    SQLObject_list_ptr tmp1 = ListTran::tran_class<OracleMultiInsertStatement_ConditionalInsertClauseItem, SQLObject>(items);
    acceptChild(visitor, tmp1);
    acceptChild(visitor, elseItem);
  }
  visitor->endVisit(SharedObject(OracleMultiInsertStatement_ConditionalInsertClause));
}

SQLExpr_ptr OracleMultiInsertStatement_ConditionalInsertClauseItem::getWhen()
{
  return when;
}

void OracleMultiInsertStatement_ConditionalInsertClauseItem::setWhen(SQLExpr_ptr when)
{
  this->when = when;
}

OracleMultiInsertStatement_InsertIntoClause_ptr OracleMultiInsertStatement_ConditionalInsertClauseItem::getThen()
{
  return then;
}

void OracleMultiInsertStatement_ConditionalInsertClauseItem::setThen(OracleMultiInsertStatement_InsertIntoClause_ptr then)
{
  this->then = then;
}

// @Override
void OracleMultiInsertStatement_ConditionalInsertClauseItem::accept0(OracleASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(OracleMultiInsertStatement_ConditionalInsertClauseItem)))
  {
    acceptChild(visitor, when);
    acceptChild(visitor, then);
  }
  visitor->endVisit(SharedObject(OracleMultiInsertStatement_ConditionalInsertClauseItem));
}

OracleMultiInsertStatement_InsertIntoClause::OracleMultiInsertStatement_InsertIntoClause()
{
}

OracleReturningClause_ptr OracleMultiInsertStatement_InsertIntoClause::getReturning()
{
  return returning;
}

void OracleMultiInsertStatement_InsertIntoClause::setReturning(OracleReturningClause_ptr returning)
{
  this->returning = returning;
}

SQLErrorLoggingClause_ptr OracleMultiInsertStatement_InsertIntoClause::getErrorLogging()
{
  return errorLogging;
}

void OracleMultiInsertStatement_InsertIntoClause::setErrorLogging(SQLErrorLoggingClause_ptr errorLogging)
{
  this->errorLogging = errorLogging;
}

// @Override
void OracleMultiInsertStatement_InsertIntoClause::accept0(SQLASTVisitor_ptr visitor)
{
  this->accept0(std::dynamic_pointer_cast<OracleASTVisitor>(visitor));
}

// @Override
void OracleMultiInsertStatement_InsertIntoClause::accept0(OracleASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(OracleMultiInsertStatement_InsertIntoClause)))
  {
    this->acceptChild(visitor, tableSource);
    SQLObject_list_ptr tmp1 = ListTran::tran_class<SQLExpr, SQLObject>(columns);
    this->acceptChild(visitor, tmp1);
    SQLObject_list_ptr tmp2 = ListTran::tran_class<SQLInsertStatement_ValuesClause, SQLObject>(valuesList);
    this->acceptChild(visitor, tmp2);
    this->acceptChild(visitor, query);
    this->acceptChild(visitor, returning);
    this->acceptChild(visitor, errorLogging);
  }

  visitor->endVisit(SharedObject(OracleMultiInsertStatement_InsertIntoClause));
}

void OracleMultiInsertStatement_InsertIntoClause::cloneTo(OracleMultiInsertStatement_InsertIntoClause_ptr x)
{
  SQLInsertInto::cloneTo(x);
  if (returning != nullptr)
  {
    x->setReturning(std::dynamic_pointer_cast<OracleReturningClause>(returning->clone()));
  }
  if (errorLogging != nullptr)
  {
    x->setErrorLogging(std::dynamic_pointer_cast<SQLErrorLoggingClause>(errorLogging->clone()));
  }
}

SQLObject_ptr OracleMultiInsertStatement_InsertIntoClause::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<OracleMultiInsertStatement_InsertIntoClause>(new OracleMultiInsertStatement_InsertIntoClause());
  std::shared_ptr<OracleMultiInsertStatement_InsertIntoClause> x = std::dynamic_pointer_cast<OracleMultiInsertStatement_InsertIntoClause>(clone_tmp);
  // OracleMultiInsertStatement_InsertIntoClause x = new OracleMultiInsertStatement_InsertIntoClause();
  cloneTo(x);
  return x;
}

OracleMultiInsertStatement::OracleMultiInsertStatement()
{
  entries = std::make_shared<std::list<OracleMultiInsertStatement_Entry_ptr>>();
  hints = std::make_shared<std::list<SQLHint_ptr>>();
}

SQLHint_list_ptr OracleMultiInsertStatement::getHints()
{
  return hints;
}

void OracleMultiInsertStatement::setHints(SQLHint_list_ptr hints)
{
  this->hints = hints;
}

OracleMultiInsertStatement_Entry_list_ptr OracleMultiInsertStatement::getEntries()
{
  return entries;
}

void OracleMultiInsertStatement::addEntry(OracleMultiInsertStatement_Entry_ptr entry)
{
  if (entry != nullptr)
  {
    entry->setParent(SharedObject(OracleMultiInsertStatement));
  }
  this->entries->push_back(entry);
}

OracleMultiInsertStatement_Option_ptr OracleMultiInsertStatement::getOption()
{
  return option;
}

void OracleMultiInsertStatement::setOption(OracleMultiInsertStatement_Option_ptr option)
{
  this->option = option;
}

SQLSelect_ptr OracleMultiInsertStatement::getSubQuery()
{
  return subQuery;
}

void OracleMultiInsertStatement::setSubQuery(SQLSelect_ptr subQuery)
{
  this->subQuery = subQuery;
}

// @Override
void OracleMultiInsertStatement::accept0(OracleASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(OracleMultiInsertStatement)))
  {
    SQLObject_list_ptr tmp1 = ListTran::tran_class<OracleMultiInsertStatement_Entry, SQLObject>(this->entries);
    acceptChild(visitor, tmp1);
    acceptChild(visitor, this->subQuery);
  }
  visitor->endVisit(SharedObject(OracleMultiInsertStatement));
}
